package com.oig.sys.base.controller;

import cn.hutool.core.util.StrUtil;
import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.read.listener.PageReadListener;
import com.oig.common.exception.BadRequestException;
import com.oig.common.module.SysPageInfo;
import com.oig.common.module.SysRequest;
import com.oig.common.module.SysResponse;
import com.oig.common.validator.GroupAdd;
import com.oig.common.validator.GroupEdit;
import com.oig.sys.base.app.IAppCustomsService;
import com.oig.sys.base.dto.CustomsDto;
import com.oig.sys.base.service.ITbCountryService;
import com.oig.sys.base.service.ITbCustomsService;
import com.oig.sys.base.vo.CountryVo;
import com.oig.sys.base.vo.CustomsVo;
import com.oig.sys.log.annotation.SysLog;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RequestPart;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;

import java.util.List;
import java.util.Map;

@Tag(name = "海关管理")
@RestController
@RequestMapping("/customs")
@Slf4j
public class TbCustomsController {

    private final IAppCustomsService appCustomsService;
    private final ITbCustomsService customsService;
    private final ITbCountryService countryService;

    @Autowired
    public TbCustomsController(IAppCustomsService appCustomsService,
                               ITbCustomsService customsService,
                               ITbCountryService countryService){
        this.appCustomsService = appCustomsService;
        this.customsService = customsService;
        this.countryService = countryService;
    }


    @PreAuthorize("@pms.hasPermission('/customs/addCustoms')")
    @SysLog(value="添加海关",apiUrl="/customs/addCustoms")
    @Operation(summary = "添加海关")
    @PostMapping(value = "/addCustoms")
    public CustomsVo addCustoms(@RequestBody @Validated(GroupAdd.class) CustomsDto customsDto){
        log.info("add customs {}", customsDto);
        return this.appCustomsService.addTbCustoms(customsDto);
    }

    @PreAuthorize("@pms.hasPermission('/customs/updateCustoms')")
    @SysLog(value="修改海关",apiUrl="/customs/updateCustoms")
    @Operation(summary = "修改海关")
    @PostMapping(value = "/updateCustoms")
    public CustomsVo updateCustoms(@RequestBody @Validated(GroupEdit.class) CustomsDto customsDto){
        log.info("update customs {}",customsDto);
        return this.appCustomsService.updateTbCustoms(customsDto);
    }

    @PreAuthorize("@pms.hasPermission('/customs/cancelCustoms')")
    @SysLog(value="逻辑删除海关",apiUrl="/customs/cancelCustoms")
    @Operation(summary = "逻辑删除海关")
    @PostMapping(value = "/cancelCustoms/{id}")
    public SysResponse<Integer> cancelCustoms(@PathVariable("id") Integer id){
        log.info("cancel customs id={}", id) ;
        this.appCustomsService.cancelTbCustoms(id);
        return SysResponse.ok(id,"逻辑删除海关成功");
    }


    @Operation(summary = "查询备选海关")
    @PostMapping(value = "/findCustoms")
    public SysPageInfo<CustomsVo> findCustoms(@RequestBody SysRequest<CustomsDto> customsRequest){
        log.info("find customs {}", customsRequest) ;
        return this.customsService.findCustoms(customsRequest) ;
    }


    @PreAuthorize("@pms.hasPermission('/customs/importCustoms')")
    @SysLog(value="批量导入海关关区",apiUrl="/customs/importCustoms")
    @PostMapping("/importCustoms/{countryCode}")
    @Operation(summary = "批量导入海关关区,json 文件导入")
    public SysResponse<String> importCustoms(@PathVariable("countryCode") String countryCode, @RequestPart("jsonFile") MultipartFile jsonFile){
        log.info("import customs country:{}", countryCode);
        if (jsonFile == null || jsonFile.getSize() == 0 || StrUtil.isBlank(jsonFile.getOriginalFilename())) {
            throw new BadRequestException("空文件...");
        }
        if (StringUtils.isEmpty(countryCode)){
            throw new BadRequestException("国家地区代码必填!") ;
        }
        CountryVo countryVo = countryService.getCountryByCode(countryCode) ;
        if (countryVo==null){
            return SysResponse.failed("国家地区不存在!");
        }
        try{
            EasyExcel.read(jsonFile.getInputStream(), new PageReadListener<Map<Integer, String>>(dataList -> {
                for (Map<Integer, String> dataMap : dataList){
                    log.debug("excel data map:{}",dataMap);
                    CustomsVo customsVo = this.customsService.getByName(dataMap.get(0));
                    if (customsVo!=null){
                        log.warn("已存在关区：{}", customsVo);
                        continue;
                    }
                    CustomsDto customsDto = new CustomsDto();
                    customsDto.setCustomsCode(dataMap.get(1));
                    customsDto.setCustomsName(dataMap.get(0));
                    customsDto.setCountryCode(countryVo.getCode());
                    customsDto.setCountryName(countryVo.getName());
                    this.appCustomsService.addTbCustoms(customsDto);
                }
            })).headRowNumber(2).sheet().doRead();
        } catch (Exception e){
            log.error("file upload error", e);
            return SysResponse.failed("导入海关关区失败");
        }
        return SysResponse.ok(jsonFile.getOriginalFilename(),"导入海关关区成功");
    }



    @Operation(summary = "根据名称获取海关")
    @PostMapping(value = "/getByName")
    public CustomsVo getByName(@RequestParam("name") String name){
        log.info("get port By Name：{}",name);
        return this.customsService.getByName(name);
    }

    @Operation(summary = "根据原code获取海关")
    @PostMapping(value = "/getByOldCode")
    public CustomsVo getByOldCode(@RequestParam("oldCode") String oldCode){
        log.info("get port by old code：{}",oldCode);
        return this.customsService.getByOldCode(oldCode);
    }

    @Operation(summary = "根据原code获取海关")
    @PostMapping(value = "/getByCode")
    public CustomsVo getByCode(@RequestParam("code") String code){
        log.info("get port by code：{}",code);
        return this.customsService.getByCode(code);
    }

    @Operation(summary = "根据目的港portCode获取海关列表信息")
    @PostMapping(value = "/getByPortCode")
    public List<CustomsVo> getByPortCode(@RequestParam("portCode") String portCode){
        log.info("get portCode by code：{}",portCode);
        return this.customsService.getByPortCode(portCode);
    }

}
